package com.alibaba.citrus.cr.mn.order.center.facade.service.impl;

import com.alibaba.citrus.cr.b2b.trade.order.facade.common.SetOrderTag;
import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
import com.alibaba.citrus.cr.common.enums.ordercenter.*;
import com.alibaba.citrus.cr.common.exception.FunctionException;
import com.alibaba.citrus.cr.common.lock.SaleRedisLock;
import com.alibaba.citrus.cr.mn.order.center.common.util.AssertUtils;
import com.alibaba.citrus.cr.mn.order.center.common.util.TrimUtils;
import com.alibaba.citrus.cr.mn.order.center.facade.function.common.*;
import com.alibaba.citrus.cr.mn.order.center.facade.function.convert.ObtcSaleOrderLineIndexToResponseConvertor;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.crb2btradecenter.obtcsaleorderlineindex.model.ObtcSaleOrderLineIndex;
import com.epoch.app.mnordercenter.model.dto.*;
import com.epoch.app.mnordercenter.orderbaserequest.*;
import com.epoch.app.mnordercenter.returnorderatom.service.ReturnOrderAtomService;
import com.google.common.collect.Lists;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.alibaba.citrus.cr.mn.order.center.common.constants.RedisLockConstants.*;

/**
 * Chen.mu
 * 2023/5/11
 **/
@Primary
@Component
public class ReturnOrderAtomServiceImpl implements ReturnOrderAtomService {

    private static final Log log = Log.getLogger(ReturnOrderAtomServiceImpl.class);

    @Resource(name = "returnOrderAtomCreateService")
    private OrderAtomCreateService returnOrderAtomCreateService;
    @Resource(name = "returnOrderAtomSubmitService")
    private OrderAtomSubmitService returnOrderAtomSubmitService;
    @Resource(name = "returnOrderAtomCloseService")
    private OrderAtomCloseService returnOrderAtomCloseService;
    @Resource(name = "returnOrderAtomUpdateService")
    private OrderAtomUpdateService returnOrderAtomUpdateService;
    @Resource(name = "returnOrderAtomCancelService")
    private OrderAtomCancelService returnOrderAtomCancelService;
    @Resource(name = "returnOrderAtomQueryService")
    private OrderAtomQueryService<OrderAtomQueryListRequest, SalesOrderAtomPageQueryRequest, ReturnOrderAtomQueryResponse> returnOrderAtomQueryService;
    @Resource
    private SendMsgService sendMsgService;

    @FacadeInvoker(value = "退货订单批量创建", errorCode = "OC-02-001-01-16-006")
    @Override
    public Result<List<ReturnOrderAtomCreateResponse>> batchCreate(ReturnOrderAtomBatchCreateRequest request) {
        log.info("ReturnOrderAtomServiceImpl#batchCreate request={}", JSON.toJSONString(request));
        String lockKey = RETURN_ORDER_ATOM_PREFIX + DigestUtils.md5Hex(JSON.toJSONString(request));
        log.info("ReturnOrderAtomServiceImpl#batchCreate lockKey={}", lockKey);

        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("ReturnOrderAtomServiceImpl#batchCreate 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }

            // 移除入参里的前后空格
            TrimUtils.removeSpace(request);

            request.getOrderList().forEach(order -> {
                if (StringUtils.isNotBlank(request.getFromSys())) {
                    order.setFromSys(request.getFromSys());
                }
                if (StringUtils.isNotBlank(request.getBusinessType())) {
                    order.setBusinessType(request.getBusinessType());
                }
                if (StringUtils.isNotBlank(request.getBusinessUnitCode())) {
                    order.setBusinessUnitCode(request.getBusinessUnitCode());
                }
            });

            List<OrderAtomCreateResponse> resp = returnOrderAtomCreateService.batchCreate(request.getOrderList());
            List<ReturnOrderAtomCreateResponse> result = new ArrayList<>();
            for (OrderAtomCreateResponse x : resp) {
                ReturnOrderAtomCreateResponse response = new ReturnOrderAtomCreateResponse();
                BeanUtils.copyProperties(x, response);
                response.setSalesOrderNo(x.getSalesOrderNo());
                result.add(response);
            }
            List<ReturnOrderAtomCreateResponse> failList = result.stream().filter(p -> StringUtils.isNotBlank(p.getErrorCode())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(failList)) {
                return Result.fail(result, "OC-01-001-01-16-006", "退货订单批量创建失败");
            }
            return Result.success(result, "", "");
        } catch (Exception e) {
            log.error("ReturnOrderAtomServiceImpl#batchCreate error", e);
            throw e;
        }
    }

    @Override
    @FacadeInvoker(value = "退货订单批量取消", errorCode = "OC-02-001-01-16-017")
    public Result<List<OrderAtomCancelResponse>> batchCancel(OrderAtomBatchCancelRequest request) {
        log.info("ReturnOrderAtomServiceImpl#batchCancel request={}", JSON.toJSONString(request));
        String lockKey = RETURN_ORDER_ATOM_PREFIX + DigestUtils.md5Hex(JSON.toJSONString(request));
        log.info("ReturnOrderAtomServiceImpl#batchCancel lockKey={}", lockKey);

        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("ReturnOrderAtomServiceImpl#batchCancel 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }

            List<OrderAtomCancelResponse> resp = returnOrderAtomCancelService.batchCancel(request);
            return Result.success(resp, "", "");
        } catch (Exception e) {
            log.error("ReturnOrderAtomServiceImpl#batchCancel error", e);
            throw e;
        }
    }

    @FacadeInvoker(value = "批量提交退货订单", errorCode = "OC-02-001-01-16-018")
    @Override
    public Result<List<OrderAtomSubmitResponse>> batchSubmit(OrderAtomBatchSubmitRequest request) {
        log.info("ReturnOrderAtomServiceImpl#batchSubmit request={}", JSON.toJSONString(request));
        String lockKey = RETURN_ORDER_ATOM_PREFIX + DigestUtils.md5Hex(JSON.toJSONString(request));
        log.info("ReturnOrderAtomServiceImpl#batchSubmit lockKey={}", lockKey);

        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("ReturnOrderAtomServiceImpl#batchSubmit 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }

            log.error("ReturnOrderAtomServiceImpl#batchSubmit request={}", JSONObject.toJSONString(request));
            // 销售订单提交服务 +  SAP创单消息发送
            List<OrderAtomSubmitRequest> orderList = request.getOrderList();
            if (CollectionUtils.isEmpty(orderList)) {
                throw new FunctionException("OC-01-001-01-15-001", "单据列表");
            }
            orderList.forEach(order -> {
                if (StringUtils.isNotBlank(request.getFromSys())) {
                    order.setFromSys(request.getFromSys());
                }
                if (StringUtils.isNotBlank(request.getBusinessType())) {
                    order.setBusinessType(request.getBusinessType());
                }
                if (StringUtils.isNotBlank(request.getBusinessUnitCode())) {
                    order.setBusinessUnitCode(request.getBusinessUnitCode());
                }
            });
            List<OrderAtomSubmitResponse> submitResponses = returnOrderAtomSubmitService.batchSubmit(orderList);
            if (CollectionUtils.isNotEmpty(submitResponses)) {
                // 发送消息通知来源系统
                List<PushOrderInfoToMnSideRequestOrderInfo> pushOrderInfoList = new ArrayList<>();
                for (OrderAtomSubmitResponse submitResponse : submitResponses) {
                    pushOrderInfoList.add(PushOrderInfoToMnSideRequestOrderInfo.builder()
                            .salesOrderNo(submitResponse.getSalesOrderNo())
                            .orderStatus(SalesOrderPushStatusEnum.FAIL_UPDATE.getOrderStatusCode())
                            .message(submitResponse.getMessage())
                            .build());
                }
                // 发送kafka消息通知应用端处理结果
//                sendMsgService.sendMsgToNYK(pushOrderInfoList);
                CommonAsyncMessageResponse commonAsyncMessageResponse = new CommonAsyncMessageResponse();
                commonAsyncMessageResponse.setEventCode(AsyncMessageEventEnum.RETURN_ORDER_UPDATE.getValue());
                commonAsyncMessageResponse.setEventName(AsyncMessageEventEnum.RETURN_ORDER_UPDATE.getLabel());
                commonAsyncMessageResponse.setEventTime(String.valueOf(new Date().getTime()));
                commonAsyncMessageResponse.setFromSys(request.getOrderList().get(0).getFromSys());
                commonAsyncMessageResponse.setBusinessUnitCode(request.getOrderList().get(0).getBusinessUnitCode());
                commonAsyncMessageResponse.setData(pushOrderInfoList);
                sendMsgService.sendMsgToSendKafka(commonAsyncMessageResponse);
                log.info("ReturnOrderAtomServiceImpl#batchSubmit sendMsgToSendKafka message={}", commonAsyncMessageResponse);
            }
            return Result.success(Lists.newArrayList(), "", "");
        } catch (Exception e) {
            log.error("ReturnOrderAtomServiceImpl#batchSubmit error", e);
            throw e;
        }
    }

    @FacadeInvoker(value = "更新退货订单", errorCode = "OC-02-001-01-16-019")
    @Override
    public Result<OrderAtomUpdateResponse> update(OrderAtomUpdateRequest request) {
        log.info("ReturnOrderAtomServiceImpl#update request={}", JSON.toJSONString(request));
        String lockKey = RETURN_ORDER_ATOM_PREFIX + request.getSalesOrderNo();
        log.info("ReturnOrderAtomServiceImpl#update lockKey={}", lockKey);
        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("ReturnOrderAtomServiceImpl#update 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }

            OrderAtomUpdateResponse response = returnOrderAtomUpdateService.update(request);
            if(StringUtils.isNotBlank(response.getErrorCode())){
                return Result.fail(response, "", "");
            }
            return Result.success(response, "", "");
        } catch (Exception e) {
            log.error("ReturnOrderAtomServiceImpl#update error", e);
            throw e;
        }
    }

    @FacadeInvoker(value = "批量关闭退货订单", errorCode = "OC-02-001-01-16-013")
    @Override
    public Result<List<OrderAtomCloseResponse>> batchClose(OrderAtomBatchCloseRequest request) {
        log.info("ReturnOrderAtomServiceImpl#batchClose request={}", JSON.toJSONString(request));
        String lockKey = RETURN_ORDER_ATOM_PREFIX + DigestUtils.md5Hex(JSON.toJSONString(request));
        log.info("ReturnOrderAtomServiceImpl#batchClose lockKey={}", lockKey);

        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("ReturnOrderAtomServiceImpl#batchClose 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }
            List<OrderAtomCloseResponse> closeResponses = returnOrderAtomCloseService.batchClose(request);
            if (CollectionUtils.isNotEmpty(closeResponses)) {
                // 发送消息通知来源系统
                List<PushOrderInfoToMnSideRequestOrderInfo> pushOrderInfoList = new ArrayList<>();
                for (OrderAtomCloseResponse closeResponse : closeResponses) {
                    if (Boolean.TRUE.equals(closeResponse.getSuccess())) {
                        // 成功的不发kafka消息，要基于sap关闭回调结果发kafka消息
                        continue;
                    }
                    pushOrderInfoList.add(PushOrderInfoToMnSideRequestOrderInfo.builder()
                            .salesOrderNo(closeResponse.getSalesOrderNo())
                            .lineNum(closeResponse.getLineNum())
                            .orderStatus(SalesOrderPushStatusEnum.FAIL_REFUSED.getOrderStatusCode())
                            .message(closeResponse.getMessage())
                            .build());
                }
                // 发送kafka消息通知应用端处理结果
//                sendMsgService.sendMsgToNYK(pushOrderInfoList);
                if (CollectionUtils.isNotEmpty(pushOrderInfoList)) {
                    CommonAsyncMessageResponse commonAsyncMessageResponse = new CommonAsyncMessageResponse();
                    commonAsyncMessageResponse.setEventCode(AsyncMessageEventEnum.RETURN_ORDER_REFUSED.getValue());
                    commonAsyncMessageResponse.setEventName(AsyncMessageEventEnum.RETURN_ORDER_REFUSED.getLabel());
                    commonAsyncMessageResponse.setEventTime(String.valueOf(new Date().getTime()));
                    commonAsyncMessageResponse.setFromSys(request.getOrderList().get(0).getFromSys());
                    commonAsyncMessageResponse.setBusinessUnitCode(request.getOrderList().get(0).getBusinessUnitCode());
                    commonAsyncMessageResponse.setData(pushOrderInfoList);
                    sendMsgService.sendMsgToSendKafka(commonAsyncMessageResponse);
                    log.info("ReturnOrderAtomServiceImpl#batchClose sendMsgToSendKafka message={}", commonAsyncMessageResponse);
                }
            }
        } catch (Exception e) {
            log.error("ReturnOrderAtomServiceImpl#batchClose error", e);
            throw e;
        }
        return Result.success(Lists.newArrayList(), "", "");
    }

    /**
     * 批量查询
     */
    @FacadeInvoker(value = "订单批量查询", errorCode = "OC-01-003-01-16-008")
    @Override
    public Result<List<ReturnOrderAtomQueryResponse>> loadForPage(SalesOrderAtomPageQueryRequest request) {
        // 校验销售订单的单据类型
        List<String> salesOrderType = request.getSalesOrderType();
        if (CollectionUtils.isEmpty(salesOrderType)) {
            request.setSalesOrderType(ReturnOrderTypeEnum.codes());
        } else {
            salesOrderType.forEach(tmpSalesOrderType -> {
                if (Objects.isNull(ReturnOrderTypeEnum.of(tmpSalesOrderType))) {
                    throw new FunctionException("OC-01-001-01-16-027");
                }
            });
        }
        PageResult<List<ReturnOrderAtomQueryResponse>> result = returnOrderAtomQueryService.page(request, SetOrderTag.RETURN);
        Result<List<ReturnOrderAtomQueryResponse>> success = Result.success(result.getContent(), "", "");
        success.setTotal(result.getTotal());
        return success;
    }

    /**
     * 精准查询
     */
    @FacadeInvoker(value = "订单精准查询", errorCode = "OC-01-003-01-16-008")
    @Override
    public Result<List<ReturnOrderAtomQueryResponse>> loadListForPage(OrderAtomQueryListRequest request) {
        PageResult<List<ReturnOrderAtomQueryResponse>> result = returnOrderAtomQueryService.listPage(request);
        Result<List<ReturnOrderAtomQueryResponse>> success = Result.success(result.getContent(), "", "");
        success.setTotal(result.getTotal());
        return success;
    }

    /**
     * 明细查询
     */
    @FacadeInvoker(value = "明细查询", errorCode = "OC-01-003-01-16-008")
    @Override
    public Result<List<ReturnOrderQueryDetailResponse>> loadDetailForPage(ReturnOrderAtomPageQueryRequest request) {
        List<String> salesOrderType = request.getSalesOrderTypeList();
        if (CollectionUtils.isEmpty(salesOrderType)) {
            request.setSalesOrderTypeList(ReturnOrderTypeEnum.codes());
        } else {
            salesOrderType.forEach(tmpSalesOrderType -> {
                if (Objects.isNull(ReturnOrderTypeEnum.of(tmpSalesOrderType))) {
                    throw new FunctionException("OC-01-001-01-16-027");
                }
            });
        }
        if (StringUtils.isBlank(request.getOrderCategoryCode())) {
            request.setOrderCategoryCodeList(Lists.newArrayList(OrderCategoryEnum.COMPANY.getCode(), OrderCategoryEnum.STOCK.getCode()));
        } else {
            AssertUtils.lengthCheck(request.getOrderCategoryCode(), 50, false, "OC-01-001-01-15-004", "订单类别编码");
            AssertUtils.isTrue(!OrderCategoryEnum.codes().contains(request.getOrderCategoryCode()), "OC-01-001-01-15-006", "订单类别编码");
        }
        if (StringUtils.isBlank(request.getOrderTag())) {
            request.setOrderTag(SetOrderTag.RETURN);
        }
        SalesOrderAtomPageQueryRequest salesOrderAtomPageQueryRequest = new SalesOrderAtomPageQueryRequest();
        BeanUtils.copyProperties(request, salesOrderAtomPageQueryRequest);
        Map<String, String> createTimeMap = AssertUtils.timeFormatCheck(salesOrderAtomPageQueryRequest.getCreateBeginTime(), salesOrderAtomPageQueryRequest.getCreateEndTime(), "创建时间（开始时间）", "创建时间（结束时间）", AssertUtils.TYPE_TIME);
        salesOrderAtomPageQueryRequest.setCreateBeginTime(createTimeMap.get(AssertUtils.START_TIME));
        salesOrderAtomPageQueryRequest.setCreateEndTime(createTimeMap.get(AssertUtils.END_TIME));
        Result<List<ObtcSaleOrderLineIndex>> listResult = returnOrderAtomQueryService.detailListPage(salesOrderAtomPageQueryRequest);
        List<ReturnOrderQueryDetailResponse> response = ObtcSaleOrderLineIndexToResponseConvertor.convertReturnOrderQueryDetailResponse(listResult);
        Result<List<ReturnOrderQueryDetailResponse>> success = Result.success(response, "", "");
        success.setTotal(listResult.getTotal());
        return success;
    }

}
